package com.xuecheng.search.service;

import com.xuecheng.framework.domain.course.CoursePub;
import com.xuecheng.framework.domain.course.TeachplanMediaPub;
import com.xuecheng.framework.domain.search.CourseSearchParam;
import com.xuecheng.framework.model.response.CommonCode;
import com.xuecheng.framework.model.response.QueryResponseResult;
import com.xuecheng.framework.model.response.QueryResult;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class EsCourseService {

    @Value("${xuecheng.elasticsearch.course.index}")
    private String index;
    @Value("${xuecheng.elasticsearch.media.index}")
    private String media_index;
    @Value("${xuecheng.elasticsearch.course.type}")
    private String type;
    @Value("${xuecheng.elasticsearch.media.type}")
    private String media_type;
    @Value("${xuecheng.elasticsearch.course.source_field}")
    private String source_field;
    @Value("${xuecheng.elasticsearch.media.source_field}")
    private String media_source_field;

    @Autowired
    RestHighLevelClient client;


     public QueryResponseResult<CoursePub> list(int page, int size, CourseSearchParam courseSearchParam) {
        //设置索引
        SearchRequest searchRequest=new SearchRequest(index);
        //设置类型
        searchRequest.types(type);
        SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
        //设置过滤字段
        String[] source_field_array=source_field.split(",");
        searchSourceBuilder.fetchSource(source_field_array,new String[]{});
        //创建布尔查询对象
         BoolQueryBuilder boolQueryBuilder= QueryBuilders.boolQuery();
        //搜索条件
         //根据关键字搜索
         if(StringUtils.isNotEmpty(courseSearchParam.getKeyword())){
           MultiMatchQueryBuilder matchQueryBuilder= QueryBuilders.multiMatchQuery(courseSearchParam.getKeyword(),"name","description","teachplan")
                    .minimumShouldMatch("70%").field("name",10);
            boolQueryBuilder.must(matchQueryBuilder);
         }
         //根据分类
        if(StringUtils.isNotEmpty(courseSearchParam.getMt())){
            //根据一级分类
            System.out.println(courseSearchParam.getMt());
            boolQueryBuilder.filter(QueryBuilders.termQuery("mt",courseSearchParam.getMt()));
        }
         if(StringUtils.isNotEmpty(courseSearchParam.getSt())){
             //根据er级分类
             boolQueryBuilder.filter(QueryBuilders.termQuery("st",courseSearchParam.getSt()));
         }
         if(StringUtils.isNotEmpty(courseSearchParam.getGrade())){
             //根据难度等级分类
             boolQueryBuilder.filter(QueryBuilders.termQuery("grade",courseSearchParam.getGrade()));
         }
         //设置分页参数
         if(page<=0){
             page=1;
         }
         if(size<=0){
             size=2;
         }
         int from = (page-1)*size;
        //将布尔查询对象放入searchSourceBuilder中
         searchSourceBuilder.from(from);//设置起始记录下标
         searchSourceBuilder.size(size);//每页显示记录数
         //设置高亮
         HighlightBuilder highlightBuilder=new HighlightBuilder();
         highlightBuilder.preTags("<font class='eslight'>");
         highlightBuilder.postTags("</font>");
         //设置高亮字段
         highlightBuilder.fields().add(new HighlightBuilder.Field("name"));
         searchSourceBuilder.highlighter(highlightBuilder);
         searchSourceBuilder.query(boolQueryBuilder);
        //请求搜索
        searchRequest.source(searchSourceBuilder);
         QueryResult<CoursePub> queryResult = new QueryResult<>();
         List<CoursePub> list=new ArrayList<>();
         try {
             //执行搜索获取相应结果
             SearchResponse searchResponse = client.search(searchRequest);
             //获得返回数据
             SearchHits hits=searchResponse.getHits();
             //获取总记录数
             Long totals=hits.getTotalHits();
             queryResult.setTotal(totals);
             SearchHit[] searchHits=hits.getHits();
             for (SearchHit hit:searchHits
                  ) {
                 CoursePub coursePub=new CoursePub();
                 //获取源文档
                Map<String,Object> sourceAsMap=  hit.getSourceAsMap();
                 String name = (String) sourceAsMap.get("name");
                 //获取id字段
                 String id= (String) sourceAsMap.get("id");
                 coursePub.setId(id);
                 //获取高亮字段
               Map<String, HighlightField> hightLightFields=  hit.getHighlightFields();
               if(hightLightFields!=null){
                   HighlightField highlightFieldName=hightLightFields.get("name");
                   //取出段信息，被高亮标签分隔的段落
                   if(highlightFieldName!=null){
                       Text[] fragments = highlightFieldName.fragments();
                       //拼接
                       StringBuffer stringBuffer=new StringBuffer();
                       for (Text text:fragments
                       ) {
                           stringBuffer.append(text);
                       }
                       name=stringBuffer.toString();
                   }
               }
                 coursePub.setName(name);
                //图片
                 String pic = (String) sourceAsMap.get("pic");
                 coursePub.setPic(pic);
                 //一级分类，二级分类，难度查询
                 String mt= (String) sourceAsMap.get("mt");
                 String st= (String) sourceAsMap.get("st");
                 String grade= (String) sourceAsMap.get("grade");
                 coursePub.setMt(mt);
                 coursePub.setSt(st);
                 coursePub.setGrade(grade);
                //价格
                 Double price = null;
                 try {
                     if(sourceAsMap.get("price")!=null ){
                         price = (Double) sourceAsMap.get("price");
                     }
                 } catch (Exception e) {
                     e.printStackTrace();
                 }
                 coursePub.setPrice(price);
                 Double price_old = null;
                 try {
                     if(sourceAsMap.get("price_old")!=null ){
                         price_old = (Double) sourceAsMap.get("price_old");
                     }
                 } catch (Exception e) {
                     e.printStackTrace();
                 }
                 coursePub.setPrice_old(price_old);
                list.add(coursePub);
             }
         } catch (IOException e) {
             e.printStackTrace();
         }
         queryResult.setList(list);
        QueryResponseResult<CoursePub> queryResponseResult= new QueryResponseResult<CoursePub>(CommonCode.SUCCESS,queryResult);
         return queryResponseResult;
     }

    public Map<String, CoursePub> searchById(String id) {
        SearchRequest searchRequest=new SearchRequest(index);
        searchRequest.types(type);
        SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
        //设置查询条件
        searchSourceBuilder.query(QueryBuilders.termQuery("_id",id));
        searchRequest.source(searchSourceBuilder);
        //执行搜索
        SearchResponse searchResponse=null;
        try {
           searchResponse= client.search(searchRequest);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //获取搜索结果
        SearchHits hits=  searchResponse.getHits();
        SearchHit[] searchHits=hits.getHits();
        Map<String,CoursePub> map=new HashMap<>();
        for (SearchHit hit:searchHits
             ) {
            CoursePub coursePub=new CoursePub();
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            String courseId = (String) sourceAsMap.get("id");
            String name = (String) sourceAsMap.get("name");
            String grade = (String) sourceAsMap.get("grade");
            String charge = (String) sourceAsMap.get("charge");
            String pic = (String) sourceAsMap.get("pic");
            String description = (String) sourceAsMap.get("description");
            String teachplan = (String) sourceAsMap.get("teachplan");
            coursePub.setId(id);
            coursePub.setName(name);
            coursePub.setPic(pic);
            coursePub.setGrade(grade);
            coursePub.setTeachplan(teachplan);
            coursePub.setDescription(description);
            coursePub.setCharge(charge);
            map.put(courseId,coursePub);
        }
        return map;
    }

    public QueryResponseResult<TeachplanMediaPub> getmedia(String[] teachplanIds) {
        SearchRequest searchRequest=new SearchRequest(media_index);
        searchRequest.types(media_type);
        SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
        //添加过滤字段
        String[] media_fields=media_source_field.split(",");
        searchSourceBuilder.fetchSource(media_fields,new String[]{});
        //查询条件，根据课程计划id查询(可传入多个id)
        searchSourceBuilder.query(QueryBuilders.termsQuery("teachplan_id",teachplanIds));
        //封装搜索request
        searchRequest.source(searchSourceBuilder);
        //执行搜索获取搜索结果
        SearchResponse searchResponse=null;
        try {
           searchResponse= client.search(searchRequest);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //获取搜索结果
        SearchHits hits = searchResponse.getHits();
        long total=hits.getTotalHits();
       SearchHit[] searchHits= hits.getHits();
       List<TeachplanMediaPub> teachplanMediaPubList=new ArrayList<>();
        for (SearchHit hit:searchHits
             ) {
            TeachplanMediaPub teachplanMediaPub=new TeachplanMediaPub();
            Map<String,Object> sourceAsMap=hit.getSourceAsMap();
            //取出课程计划媒资信息
            String courseid = (String) sourceAsMap.get("courseid");
            String media_id = (String) sourceAsMap.get("media_id");
            String media_url = (String) sourceAsMap.get("media_url");
            String teachplan_id = (String) sourceAsMap.get("teachplan_id");
            String media_fileoriginalname = (String) sourceAsMap.get("media_fileoriginalname");
            teachplanMediaPub.setCourseId(courseid);
            teachplanMediaPub.setMediaUrl(media_url);
            teachplanMediaPub.setMediaFileOriginalName(media_fileoriginalname);
            teachplanMediaPub.setMediaId(media_id);
            teachplanMediaPub.setTeachplanId(teachplan_id);

            teachplanMediaPubList.add(teachplanMediaPub);
        }
        QueryResult<TeachplanMediaPub> queryResult=new QueryResult<>();
        queryResult.setList(teachplanMediaPubList);
        queryResult.setTotal(total);
        return new QueryResponseResult<TeachplanMediaPub>(CommonCode.SUCCESS,queryResult);
    }
}
